Antes de comenzar con nuestra optimización de cartera, utilizando la teoría del portafolio de Markowitz, designaremos las configuraciones iniciales para el trabajo, comenzando con la verificación, instalación y carga de los paquetes a utilizar para el caso, luego de ello, al mismo tiempo hacemos unas configuraciones aparte para el entorno de trabajo propiamente tal (no es necesario para el markdown, sin embargo, para aquellos que quieran replicar el modelo, les sea útil), con esto todo
knitr::opts_chunk$set(echo = TRUE, include = TRUE, fig.align = "center",fig.width = 10, fig.height = 8, message = FALSE, warning = FALSE)
#############################################################################
# Portfolio Opimization
# Author: Matías Vicuña Cofré
#############################################################################
#******************** Configuraciones e Inicializacion *********************#
#############################################################################
{
# Librerías
{
# Lista de paquetes que quieres verificar
paquetes <- c("tidyverse","readxl","janitor","skimr","scales","ggthemes",
"tseries","fPortfolio","knitr","kableExtra","gplots",
"plotly", "lubridate")
# Verificar e instalar paquetes que no estén instalados
for (paquete in paquetes) {
if (!require(paquete, character.only = TRUE)) {
install.packages(paquete)
}
}
remove(paquetes)
# Activacion Librerias
suppressPackageStartupMessages({
library(tidyverse)
library(readxl)
library(janitor)
library(skimr)
library(scales)
library(ggthemes)
library(tseries)
library(fPortfolio)
library(knitr)
library(kableExtra)
library(plotly)
library(lubridate)
})
}
# Configuraciones Entorno de Trabajo
{
# Limpiamos el entorno de trabajo
rm(list = ls())
# Limpiamos la Memoria (RAM)
gc(reset = TRUE)
# Limpiamos la consola
cat("\014")
# De número científico a natural
options(scipen = 999)
}
}
Luego de las configuraciones, generamos la primera muestra de datos a
utilizar, usando el paquete tseries, como primer ejemplo,
utilizaremos el índice S&P 500 Dow Jones, al cuál observaremo su
precio histórico desde Enero del 2000 hasta el 31 de diciembre del 2023,
usaremos su ticket de Yahoo Finance (^GSPC) (veáse más detalle del
índice aquí).
Junto con ello, usamos el paquete skimr para realizar un
análisis estadístico básico de la serie con los precios históricos,
teniendo su media, percentiles y demás detalles.
# Carga serie S&P 500.
SP500 <- get.hist.quote(
instrument = "^GSPC",
start = as.Date("2000-01-01"),
end = as.Date("2023-12-31"),
quote = "AdjClose"
)
## time series starts 2000-01-03
## time series ends 2023-12-29
# Renombramos la base original
colnames(SP500) <- "SP500"
# Ajustamos la muestra
SP_500 <- SP500 %>%
as_tibble() %>%
mutate(Fecha = as_date(time(SP500))) %>%
rename(Precio = SP500)
# Generamos tabla resumen de precios históricos
knitr::kable(skim_without_charts(SP_500$Precio), align = "c", format = "html")
| skim_type | skim_variable | n_missing | complete_rate | numeric.mean | numeric.sd | numeric.p0 | numeric.p25 | numeric.p50 | numeric.p75 | numeric.p100 |
|---|---|---|---|---|---|---|---|---|---|---|
| numeric | data | 0 | 1 | 1973.587 | 1061.336 | 676.53 | 1191.38 | 1457.34 | 2584.84 | 4796.56 |
Ya teniendo la serie cargada, generamos ahora un pequeño gráfico que entrega el rendimiento histórico desde el 2000 al 2023 del precio ajustado del indicador.
Para ello, hacemos uso de un recursos super relevantes para el
análisis y visualización de datos: ggplot2, con este
paquete y usando de adicional para la interacción el paquete
plotly, tenemos un gráfico que nos entrega en detalle e
intuitivamente el desarrollo de este mercado Norteamericano.
# Generamos el gráfico
int_plot_SP500 <- SP_500 %>%
ggplot(mapping = aes(x = Fecha,
y = Precio)) +
geom_line(aes(y = Precio),
color = "blue4") +
labs(x = "Años",
y = "Precio $USD",
title = "Precio Ajustado S&P 500",
subtitle = "En dólares") +
theme_minimal() +
theme(axis.title.x = element_text(size = 12,
face = "bold"),
axis.title.y = element_text(size = 12,
face = "bold"),
plot.title = element_text(size = 20,
face = "bold",
hjust = 0.5),
plot.subtitle = element_text(size = 20,
face = "bold",
hjust = 0.5))
# Generamos el gráfico de forma interactiva
ggplotly(int_plot_SP500)
Siguiendo con esta ídea, ahora generaremos una cartera, la cuál se compondrá de a lo menos 10 tipos de empresas, para este ejemplo, usaremos empresas que cotizan en la bolsa de Nueva York, especificamente serán las siguientes:
Con este listado de empresas, ahora construiremos nuestra base.
# Datos Previos
tickets <- c("KO", "PEP", "JNJ", "WMT", "TGT", "AAPL", "MSFT", "AMZN")
portafolio <- tibble()
start_port <- as.Date("2000-01-01")
end_port <- as.Date("2023-12-31")
# Iteración de Recopilación de Series
for (i in seq_along(tickets)) {
data <- get.hist.quote(
instrument = tickets[i],
start = start_port,
end = end_port,
quote = "Adjusted"
)
# Verifica si el objeto portafolio está vacío
if (nrow(portafolio) == 0) {
portafolio <- data
} else {
# Combina las series temporales por columna
portafolio <- cbind(portafolio, data)
}
}
## time series starts 2000-01-03
## time series ends 2023-12-29
## time series starts 2000-01-03
## time series ends 2023-12-29
## time series starts 2000-01-03
## time series ends 2023-12-29
## time series starts 2000-01-03
## time series ends 2023-12-29
## time series starts 2000-01-03
## time series ends 2023-12-29
## time series starts 2000-01-03
## time series ends 2023-12-29
## time series starts 2000-01-03
## time series ends 2023-12-29
## time series starts 2000-01-03
## time series ends 2023-12-29
# Asigna nombres de columna al portafolio
colnames(portafolio) <- tickets
# Extraemos la fecha de la base (para gráficar)
Fecha <- time(portafolio)
# Imprime el resultado
head(portafolio)
## KO PEP JNJ WMT TGT AAPL MSFT
## 2000-01-03 14.54959 20.37323 24.88615 43.55595 22.83883 0.8472066 36.13226
## 2000-01-04 14.56573 19.85526 23.97507 41.92614 21.84842 0.7757788 34.91170
## 2000-01-05 14.69477 19.37182 24.22815 41.07053 21.35322 0.7871309 35.27982
## 2000-01-06 14.71089 20.23508 24.98739 41.51871 20.34302 0.7190137 34.09802
## 2000-01-07 15.67871 20.78759 26.05031 44.65604 21.39284 0.7530728 34.54361
## 2000-01-10 15.17867 20.37323 25.39232 43.84114 20.97688 0.7398275 34.79548
## AMZN
## 2000-01-03 4.468750
## 2000-01-04 4.096875
## 2000-01-05 3.487500
## 2000-01-06 3.278125
## 2000-01-07 3.478125
## 2000-01-10 3.459375
Teniendo ya conformada la cartera, visualizamos la evolución histórica de cada serie
# Creamos un reshape "wide to long" para facilitar la graficación
portafolio_long <- cbind(Fecha,as_tibble(portafolio)) %>%
gather(key = "Ticket", value = "Precio", -Fecha)
# Creamos el gráfico de series de tiempo
int_plot_portafolio <- ggplot(portafolio_long,
aes(x = Fecha, y = Precio, group = Ticket, color = Ticket)) +
geom_line(aes(y = Precio)) +
facet_wrap(~Ticket, scales = "free_y") +
labs(title = "Evolución Histórica",
x = "Fecha", y = "Precio $USD") +
scale_color_calc() +
theme_minimal() +
theme(axis.title.x = element_text(size = 15, face = "bold"),
axis.title.y = element_text(size = 15, face = "bold"),
plot.title = element_text(size = 20, face = "bold", hjust = 0.5),
axis.text.x = element_text(face = "bold", vjust = 1),
legend.position = "none")
# Agregamos la interacción
ggplotly(int_plot_portafolio)
Posterior a esto, crearemos los beneficios de cada serie (incluida el S&P 500), añadiendo además una normalización logartímica para reescalar la muestra.
# Diferenciamos la cartera
dif_log_portafolio <- round(diff(log(portafolio)), digits = 6)
head(dif_log_portafolio)
## KO PEP JNJ WMT TGT AAPL
## 2000-01-04 0.001108 -0.025753 -0.037297 -0.038137 -0.044333 -0.088077
## 2000-01-05 0.008820 -0.024649 0.010500 -0.020619 -0.022926 0.014527
## 2000-01-06 0.001097 0.043598 0.030856 0.010854 -0.048465 -0.090514
## 2000-01-07 0.063716 0.026938 0.041659 0.072845 0.050318 0.046282
## 2000-01-10 -0.032413 -0.020134 -0.025583 -0.018417 -0.019635 -0.017745
## 2000-01-11 0.033441 -0.003396 0.003316 -0.014981 0.029770 -0.052505
## MSFT AMZN
## 2000-01-04 -0.034364 -0.086884
## 2000-01-05 0.010489 -0.161039
## 2000-01-06 -0.034072 -0.061914
## 2000-01-07 0.012983 0.059222
## 2000-01-10 0.007265 -0.005405
## 2000-01-11 -0.025947 -0.035866
# Diferenciamos el indice S&P 500
dif_log_SP500 <- round(diff(log(SP500)), digits = 6)
head(dif_log_SP500)
## SP500
## 2000-01-04 -0.039099
## 2000-01-05 0.001920
## 2000-01-06 0.000955
## 2000-01-07 0.026730
## 2000-01-10 0.011128
## 2000-01-11 -0.013149
Gráficamente esto se ve de la siguiente manera:
# Ajustes a la muestra (formateo de zoo a tibble)
port_SP_long <- merge(dif_log_portafolio,dif_log_SP500)
Time_diff <- time(port_SP_long)
# Creamos un reshape "wide to long" para facilitar la graficación
port_SP_long <- cbind(Time_diff,as_tibble(port_SP_long)) %>%
gather(key = "Serie", value = "Precio", -Time_diff)
# Creamos el gráfico de series de tiempo
int_plot_port_SP_dif <- ggplot(port_SP_long,
aes(x = Time_diff,
y = Precio,
group = Serie,
color = Serie)) +
geom_line(aes(y = Precio)) +
facet_wrap(~Serie, scales = "free_y") +
labs(title = "Evolución Histórica",
x = "Fecha", y = "Precio $USD") +
scale_color_calc() +
theme_minimal() +
theme(axis.title.x = element_text(size = 15, face = "bold"),
axis.title.y = element_text(size = 15, face = "bold"),
plot.title = element_text(size = 20, face = "bold", hjust = 0.5),
axis.text.x = element_text(face = "bold", vjust = 1),
legend.position = "none")
# Agregamos la interacción
ggplotly(int_plot_port_SP_dif)
Copyright © 2024 Matías Vicuña Cofré, Todos los Derechos Reservados.